package com.example.learnshadow;

import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.util.DisplayMetrics;

import java.io.File;
import java.lang.reflect.Method;

import dalvik.system.DexClassLoader;

/**
 * Author: chinadragon
 * Time: 2023/9/13 19:13
 */
public class PluginManagerImpl {
    /*
        1、PhoneWindow 的 setContentView 方法里  mLayoutInflater.inflate(layoutResID, mContentParent)
        2、查看 inflate 方法 里  XmlResourceParser parser = res.getLayout(resource);

        所以这里需要 Resources

     */
    //    代表插件 resource 对象
    private Resources resources;
    private DexClassLoader mDexClassLoader;
    private static PluginManagerImpl ourInstance = new PluginManagerImpl();
    private Context context;

    public void setContext(Context context) {
        this.context = context.getApplicationContext();
    }

    public void loadPath(String path) {
        /*
            android开发带有odex, oat, vdex, art等后缀的文件，都是什么含义？
            https://www.eefocus.com/article/525061.html

            https://baike.baidu.com/item/ODEX/10322643?fr=ge_ala

            https://blog.csdn.net/crr411422/article/details/129743873
         */
        File dexOutFile = context.getDir("odex", Context.MODE_PRIVATE);
        mDexClassLoader = new DexClassLoader(path, dexOutFile.getAbsolutePath(), null, context.getClassLoader());

//        Resources resources =    context.getPackageManager().getResourcesForApplication();// 通过 pms 方式获取 resources

//        虽然是 修饰关键字是  pulic, 但 下面直接 new 会报错， 查看  AssetManager 源码 注释说明 UnsupportedAppUsage，只能在系统层的使用
//        AssetManager assetManager = new AssetManager();
//        assets. 可以优化
        AssetManager assetManager = null;
        try {
            assetManager = AssetManager.class.newInstance();

            /*
                获取插件中的资源
                https://blog.csdn.net/lmq121210/article/details/100804853
             */

            Method addAssetPath = AssetManager.class.getMethod("addAssetPath", String.class);
            addAssetPath.invoke(assetManager, path);
    //   换皮肤技术类似     通用的 底层  原理 差不多
    //       一个手机上 安装 多个APP  DisplayMetrics 和 Configuration 都是一样的，所以下面可以这样写
            DisplayMetrics metrics = context.getResources().getDisplayMetrics();
            Configuration configuration = context.getResources().getConfiguration();
            resources = new Resources(assetManager, metrics, configuration);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch ( Exception e) {
            e.printStackTrace();
        }


    }

    public static PluginManagerImpl getInstance() {
        return ourInstance;
    }

    public DexClassLoader getDexClassLoader() {
        return mDexClassLoader;
    }


    public Resources getResources() {
        return resources;
    }
}
